home *** CD-ROM | disk | FTP | other *** search
/ La Traviata / La Traviata.iso / viewer / grabsc11.zip / GRABSCRN.C < prev    next >
C/C++ Source or Header  |  1990-11-16  |  10KB  |  357 lines

  1. /*****************************************************************************
  2. * Test program for the TSR.ASM module (only in tiny model)             *
  3. *                    Written by Gershon Elber, Sep. 1990  *
  4. *****************************************************************************/
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <conio.h>
  10. #include <dos.h>
  11. #include <io.h>
  12. #include "tsr.h"
  13.  
  14. #define VERSION "1.1"
  15.  
  16. #define SAVE_FILENAME_RAW "GrScr%03d.raw"
  17. #define SAVE_FILENAME_BAT "GrScr%03d.bat"
  18. #define SAVE_FILENAME_CMAP "GrScr%03d.cmp"
  19. #define SAVE_FILENAME_GIF "GrScr%03d.gif"
  20.  
  21. #define MAX_LINE_LEN 1024
  22.  
  23. typedef enum {
  24.     NO_DEVICE,
  25.     HERCULES,
  26.     CGA_LOW,
  27.     CGA_HI,
  28.     EGA_LOW,
  29.     EGA_MED,
  30.     VGA_LOW,
  31.     VGA_MED,
  32.     VGA_HI,
  33.     SVGA,
  34.     UVGA
  35. } DeviceType;
  36.  
  37. static int NumOfColors = 16, ColorMask = 15,
  38.     DeviceXMax, DeviceYMax, DeviceBase;
  39. static DeviceType Device = NO_DEVICE;
  40. static char *Usage =
  41.     "Usage: GrabScrn [-d] Device\t"
  42.     "(C) Copyright Gershon Elber, Ver " VERSION ", Sep 1990.\n"
  43.     "where: d is one digit {1..8} and Device can be one of:\n"
  44.     "       HERCULES CGAL CGAH EGAL EGAM VGAL VGAM VGAH SVGA UVGA.\n";
  45. static unsigned char ScanLine[MAX_LINE_LEN];
  46.  
  47. static void GetScanLine(unsigned char *ScanLine, int Y);
  48. static void TsrFunc(void);
  49.  
  50. /******************************************************************************
  51. * main - set and install the screen grabber.                      *
  52. ******************************************************************************/
  53. void main(int argc, char **argv)
  54. {
  55.     int far *n;
  56.     DeviceType far *d;
  57.  
  58.     NumOfColors = 16;
  59.  
  60.     if (argc > 2) {
  61.         if (argv[1][0] == '-' &&
  62.         argv[1][1] >= '1' && argv[1][1] <= '8') {
  63.         /* -digit detected: force the number of colors to use. */
  64.             NumOfColors = 2 << (argv[1][1] - '1');
  65.             argc--;
  66.             argv++;
  67.     }
  68.         else {
  69.         fprintf(stderr, "Syntax error.\n");
  70.         fprintf(stderr, Usage);
  71.         exit(2);
  72.         }
  73.     }
  74.  
  75.     if (argc != 2) {
  76.     fprintf(stderr, Usage);
  77.     exit(1);
  78.     }
  79.     if (strlen(argv[1]) < 4)
  80.     argv[1][4] = 0;             /* Trim the Device to 4 characters. */
  81.  
  82.     if (strcmp(argv[1], "HERC") == 0) {
  83.     Device = HERCULES;
  84.         NumOfColors = 2;
  85.     }
  86.     else if (strcmp(argv[1], "CGAL") == 0) {
  87.     Device = CGA_LOW;
  88.         NumOfColors = 4;
  89.     }
  90.     else if (strcmp(argv[1], "CGAH") == 0) {
  91.     Device = CGA_HI;
  92.         NumOfColors = 2;
  93.     }
  94.     else if (strcmp(argv[1], "EGAL") == 0) {
  95.     Device = EGA_LOW;
  96.     }
  97.     else if (strcmp(argv[1], "EGAM") == 0) {
  98.     Device = EGA_MED;
  99.     }
  100.     else if (strcmp(argv[1], "VGAL") == 0) {
  101.     Device = VGA_LOW;
  102.     }
  103.     else if (strcmp(argv[1], "VGAM") == 0) {
  104.     Device = VGA_MED;
  105.     }
  106.     else if (strcmp(argv[1], "VGAH") == 0) {
  107.     Device = VGA_HI;
  108.     }
  109.     else if (strcmp(argv[1], "SVGA") == 0) {
  110.     Device = SVGA;
  111.     }
  112.     else if (strcmp(argv[1], "UVGA") == 0) {
  113.     Device = UVGA;
  114.     }
  115.     else {
  116.     fprintf(stderr, "Undefined device type \"%s\".\n", argv[1]);
  117.     fprintf(stderr, Usage);
  118.     exit(2);
  119.     }
  120.  
  121.     switch (HookKbdInterrupt(TsrFunc, 0x4408 /* ALT F10 */)) {
  122.     case 0:
  123.         fprintf(stderr, "GrabScrn is installed, ALT-F10 To activate.\n");
  124.         keep(0, 0x400);
  125.         break;
  126.     case 1:
  127.         fprintf(stderr,
  128.             "GrabScrn is already installed, device set to \"%s\", %d Colors.\n",
  129.             argv[1], NumOfColors);
  130.         d = MK_FP(InstalledTSRSegment, &Device);
  131.         *d = Device;
  132.         n = MK_FP(InstalledTSRSegment, &NumOfColors);
  133.             *n = NumOfColors;
  134.         break;
  135.     case 2:
  136.         fprintf(stderr, "GrabScrn failed to install.\n");
  137.         break;
  138.     }
  139. }
  140.  
  141. /******************************************************************************
  142. * Set device parameters.                              *
  143. ******************************************************************************/
  144. static void SetDeviceParams(void)
  145. {
  146.     switch (Device) {
  147.     case HERCULES:
  148.             DeviceYMax = 350;
  149.             DeviceXMax = 720;
  150.         DeviceBase = 0xb000;
  151.         break;
  152.     case CGA_LOW:
  153.             DeviceYMax = 200;
  154.         DeviceXMax = 320;
  155.         DeviceBase = 0xb800;
  156.         break;
  157.     case CGA_HI:
  158.             DeviceYMax = 200;
  159.         DeviceXMax = 640;
  160.         DeviceBase = 0xb800;
  161.         break;
  162.     case EGA_LOW:
  163.             DeviceYMax = 200;
  164.         DeviceXMax = 640;
  165.         DeviceBase = 0xa000;
  166.         break;
  167.     case EGA_MED:
  168.             DeviceYMax = 350;
  169.             DeviceXMax = 640;
  170.             DeviceBase = 0xa000;
  171.         break;
  172.     case VGA_LOW:
  173.             DeviceYMax = 200;
  174.             DeviceXMax = 640;
  175.             DeviceBase = 0xa000;
  176.         break;
  177.     case VGA_MED:
  178.             DeviceYMax = 350;
  179.             DeviceXMax = 640;
  180.             DeviceBase = 0xa000;
  181.         break;
  182.     case VGA_HI:
  183.             DeviceYMax = 480;
  184.             DeviceXMax = 640;
  185.             DeviceBase = 0xa000;
  186.         break;
  187.     case SVGA:
  188.             DeviceYMax = 600;
  189.             DeviceXMax = 800;
  190.             DeviceBase = 0xa000;
  191.         break;
  192.     case UVGA:
  193.             DeviceYMax = 768;
  194.             DeviceXMax = 1024;
  195.             DeviceBase = 0xa000;
  196.         break;
  197.     }
  198.     ColorMask = NumOfColors - 1;
  199. }
  200.  
  201. /******************************************************************************
  202. * Update the given scan line buffer with the pixel levels of the Y line.      *
  203. * This routine is device specific, so make sure you know was you are doing    *
  204. ******************************************************************************/
  205. static void GetScanLine(unsigned char *ScanLine, int Y)
  206. {
  207.     unsigned char DeviceByte;
  208.     int i, j, k;
  209.     unsigned int DeviceOffset, Bit;
  210.     union REGS InRegs, OutRegs;
  211.  
  212.     switch (Device) {
  213.     case HERCULES:
  214.         DeviceOffset = 0x2000 * (Y % 4) + (Y / 4) * (DeviceXMax / 8);
  215.         /* In one scan lines we have DeviceXMax / 8 bytes: */
  216.         for (i = 0, k = 0; i < DeviceXMax / 8; i++) {
  217.         DeviceByte = (unsigned char) peekb(DeviceBase, DeviceOffset++);
  218.         for (j = 0, Bit = 0x80; j < 8; j++) {
  219.             ScanLine[k++] = (DeviceByte & Bit ? 1 : 0);
  220.             Bit >>= 1;
  221.         }
  222.         }
  223.         break;
  224.     case CGA_LOW:
  225.     case CGA_HI:
  226.     case EGA_LOW:
  227.     case EGA_MED:
  228.     case VGA_LOW:
  229.     case VGA_MED:
  230.     case VGA_HI:
  231.     case SVGA:
  232.     case UVGA:
  233.         InRegs.x.dx = Y;
  234.         InRegs.h.bh = 0;
  235.             InRegs.h.ah = 0x0d;                   /* BIOS Read dot. */
  236.         for (i = 0; i < DeviceXMax; i++) {
  237.             InRegs.x.cx = i;
  238.         int86(0x10, &InRegs, &OutRegs);
  239.             ScanLine[i] = OutRegs.h.al & ColorMask;
  240.         }
  241.  
  242.         /* Mark this line as done by putting a xored dot on the left. */
  243.         InRegs.h.bh = 0;
  244.         InRegs.h.ah = 0x0c;               /* BIOS Write dot (xor mode). */
  245.         InRegs.h.al = 0x81;                    /* Xor with color 1. */
  246.         InRegs.x.cx = 0;
  247.         InRegs.x.dx = Y;
  248.         int86(0x10, &InRegs, &OutRegs);
  249.         InRegs.h.bh = 0;
  250.         InRegs.h.ah = 0x0c;               /* BIOS Write dot (xor mode). */
  251.         InRegs.h.al = 0x81;                    /* Xor with color 1. */
  252.         InRegs.x.cx = 1;
  253.         InRegs.x.dx = Y;
  254.         int86(0x10, &InRegs, &OutRegs);
  255.  
  256.         if (Y == DeviceYMax - 1) {/* Last row - clear all marks we made. */
  257.         for (i = 0; i < DeviceYMax; i++) {
  258.             InRegs.h.bh = 0;
  259.             InRegs.h.ah = 0x0c;           /* BIOS Write dot (xor mode). */
  260.             InRegs.h.al = 0x81;           /* Xor back with color 1. */
  261.             InRegs.x.cx = 0;
  262.             InRegs.x.dx = i;
  263.             int86(0x10, &InRegs, &OutRegs);
  264.             InRegs.h.bh = 0;
  265.             InRegs.h.ah = 0x0c;           /* BIOS Write dot (xor mode). */
  266.             InRegs.h.al = 0x81;           /* Xor back with color 1. */
  267.             InRegs.x.cx = 1;
  268.             InRegs.x.dx = i;
  269.             int86(0x10, &InRegs, &OutRegs);
  270.                 }
  271.         }
  272.         break;
  273.     default:
  274.         break;
  275.     }
  276. }
  277.  
  278. /******************************************************************************
  279. * Function to save the current color map and a batch file that should be      *
  280. * invoked to create a gif image out of the raw data saved.              *
  281. ******************************************************************************/
  282. static void SaveColorMap(int FileNumber)
  283. {
  284.     char FileName[20];
  285.     int i, Handle;
  286.     union REGS InRegs, OutRegs;
  287.  
  288.     sprintf(FileName, SAVE_FILENAME_CMAP, FileNumber);
  289.     if ((Handle = _creat(FileName, 0)) != -1) {
  290.     if (Device == HERCULES || Device == CGA_HI) {
  291.         /* Black and White color map. */
  292.         _write(Handle, "1   0   0   0\r\n", 15);
  293.         _write(Handle, "2 255 255 255\r\n", 15);
  294.     }
  295.     else if (Device == CGA_LOW) {
  296.         /* 4 color map (palette 1 only). */
  297.         _write(Handle, "1   0   0   0\r\n", 15);
  298.         _write(Handle, "2   0 255   0\r\n", 15);
  299.         _write(Handle, "3 255   0   0\r\n", 15);
  300.         _write(Handle, "4   0 255 255\r\n", 15);
  301.     }
  302.     else {
  303.         for (i = 0; i < NumOfColors; i++) {
  304.             InRegs.h.bl = i;
  305.             InRegs.x.ax = 0x1015;
  306.             int86(0x10, &InRegs, &OutRegs);
  307.             sprintf(ScanLine, "%3d %4d %4d %4d\r\n",
  308.                     i + 1,
  309.                     OutRegs.h.dh << 2, OutRegs.h.ch << 2, OutRegs.h.cl << 2);
  310.             _write(Handle, ScanLine, strlen(ScanLine));
  311.         }
  312.     }
  313.     _close(Handle);
  314.     }
  315.  
  316.     sprintf(FileName, SAVE_FILENAME_BAT, FileNumber);
  317.     if ((Handle = _creat(FileName, 0)) != -1) {
  318.     sprintf(ScanLine, "raw2gif -s %d %d -p "
  319.                   SAVE_FILENAME_CMAP " "
  320.                           SAVE_FILENAME_RAW " > "
  321.                           SAVE_FILENAME_GIF "\r\n",
  322.                           DeviceXMax, DeviceYMax,
  323.                           FileNumber, FileNumber, FileNumber);
  324.     _write(Handle, ScanLine, strlen(ScanLine));
  325.     sprintf(ScanLine, "del "
  326.                   SAVE_FILENAME_CMAP "\r\ndel "
  327.                           SAVE_FILENAME_RAW "\r\n",
  328.                           FileNumber, FileNumber);
  329.     _write(Handle, ScanLine, strlen(ScanLine));
  330.     _close(Handle);
  331.     }
  332.  
  333. }
  334.  
  335. /******************************************************************************
  336. * This is the function get invoked when TSR gets activated.              *
  337. ******************************************************************************/
  338. static void TsrFunc(void)
  339. {
  340.     static int FileNumber = 1;
  341.     char FileName[20];
  342.     int i, Handle;
  343.  
  344.     SetDeviceParams();
  345.  
  346.     SaveColorMap(FileNumber);
  347.  
  348.     sprintf(FileName, SAVE_FILENAME_RAW, FileNumber++);
  349.     if ((Handle = _creat(FileName, 0)) != -1) {
  350.     for (i = 0; i < DeviceYMax; i++) {
  351.         GetScanLine(ScanLine, i);
  352.         _write(Handle, ScanLine, DeviceXMax);
  353.     }
  354.     _close(Handle);
  355.     }
  356. }
  357.